# -*- coding: utf-8 -*-
# CSH215

import os
import tkinter as tk
from tkinter import filedialog, messagebox, colorchooser

import ttkbootstrap as tb

from src.modules.about import AppInfoBar
from src.modules.config_manager import ConfigManager
from src.modules.excel_processor import process_excel
from src.utils.dialogCenterUtil import center_window


class ExcelApp:
    def __init__(self, root):
        self.root = root
        self.root.title("CSH Excel Tool")
        self.root.geometry("1000x1200")
        self.file_history = []

        # 初始化配置管理器
        self.config_manager = ConfigManager()
        self.current_profile = 'default'

        # 初始化配置变量
        self.color_var = tk.StringVar(value="#36648B")  # 默认标题背景颜色
        self.font_var = tk.StringVar(value='仿宋')  # 默认字体
        self.bold_var = tk.BooleanVar(value=False)  # 默认不加粗
        self.font_size_var = tk.IntVar(value=12)  # 默认字号

        self.title_font_color_var = tk.StringVar(value="#FFFFFF")  # 默认标题字体颜色

        # 标题行高设置
        self.title_height_var = tk.IntVar(value=25)
        # 内容行高设置
        self.row_height_var = tk.IntVar(value=20)

        # 列宽设置（使用字典存储各列宽度）
        self.col_width_vars = {
            'A': tk.IntVar(value=15),
            'B': tk.IntVar(value=20),
            'C': tk.IntVar(value=20),
            'D': tk.IntVar(value=20),
            'E': tk.IntVar(value=100),
            'F': tk.IntVar(value=10),
            'G': tk.IntVar(value=20),
            'H': tk.IntVar(value=10),
            'I': tk.IntVar(value=20)
        }

        # 创建一个字典来存储每个列的开关状态
        self.col_switch_vars = {
            'A': tk.BooleanVar(value=True),
            'B': tk.BooleanVar(value=True),
            'C': tk.BooleanVar(value=True),
            'D': tk.BooleanVar(value=True),
            'E': tk.BooleanVar(value=True),
            'F': tk.BooleanVar(value=True),
            'G': tk.BooleanVar(value=True),
            'H': tk.BooleanVar(value=True),
            'I': tk.BooleanVar(value=True)
        }

        self.color_preview = tb.Label(text="", width=5, background="#36648B")

        # 创建变量用于记录配置名称
        self.profile_var = tk.StringVar(value='default')

        style = tb.Style()
        style.configure("Intro.TLabel", background="#f0f4ff")
        style.configure("Log.TFrame", background="#f0f4ff")
        style.configure("LogInner.TFrame", background="#eaf6ff")
        style.configure("History.TFrame", background="#f0f4ff")

        # 软件简介
        intro = "🤑这是一个用于处理抖店客户信息Excel的工具，目的用于实现去除繁琐的重复工作......"
        intro_label = tb.Label(
            root, text=intro, anchor='center', font=('仿宋', 12), wraplength=680, style="Intro.TLabel",
            justify='center'
        )
        intro_label.pack(fill='none', expand=True, pady=(10, 10))

        # 配置文件选择区
        profile_container = tb.Frame(root)
        profile_container.pack(fill='x', padx=10, pady=(10, 0))

        profile_frame = tb.Frame(profile_container)
        profile_frame.pack(side='top', anchor='center')  # 居中对齐

        tb.Label(profile_frame, text="配置文件:", width=10).pack(side='left')

        # 配置下拉框
        self.profile_combobox = tb.Combobox(
            profile_frame, textvariable=self.profile_var, width=20, state='readonly'
        )
        self.profile_combobox.pack(side='left', padx=5)
        self.update_profile_list()  # 更新下拉列表

        # 输入框用于输入新配置名
        self.new_profile_entry = tb.Entry(profile_frame, width=20)
        self.new_profile_entry.pack(side='left', padx=5)
        self.new_profile_entry.insert(0, "新配置名")
        self.new_profile_entry.bind("<FocusIn>", self.on_entry_focus_in)
        self.new_profile_entry.bind("<FocusOut>", self.on_entry_focus_out)

        # 保存按钮
        tb.Button(
            profile_frame, text="保存或更新配置", command=self.save_new_profile, bootstyle="success"
        ).pack(side='left', padx=5)

        # 加载配置
        config = self.config_manager.get_config(self.current_profile)
        self.apply_config(config)

        # 绑定配置文件选择事件
        self.profile_combobox.bind("<<ComboboxSelected>>", self.on_profile_selected)

        # 文件选择区域
        self.file_var = tk.StringVar()
        # file_frame 居中
        file_frame = tb.Frame(root)
        file_frame.pack(expand=True)
        # Entry、Button 居中
        (tb.Entry(file_frame, textvariable=self.file_var, width=60, state='readonly', justify='center')
         .pack(side='left', padx=(0, 5)))
        (tb.Button(file_frame, text="选择Excel文件", command=self.select_file)
         .pack(side='left'))

        # 历史选择区域
        history_label = tb.Label(root, text="历史选择：", anchor='w')
        history_label.pack(fill='x', padx=10)
        self.history_frame = tb.Frame(root, style="History.TFrame", height=100)
        self.history_frame.pack(fill='x', padx=10)
        self.history_frame.pack_propagate(False)  # 固定高度
        self.refresh_history()

        # -处理按钮和自定义选择区域
        btn_frame = tb.Frame(root)

        # 在 btn_frame 中添加颜色和字体选择控件

        # 颜色选择相关控件
        color_frame = tb.Frame(btn_frame)
        color_frame.pack(side='left', padx=(0, 5), pady=10)

        # 标题背景颜色预览标签
        color_preview_label = tb.Label(color_frame, text="标题背景颜色", width=15, font='12', )
        color_preview_label.configure(foreground='black', font="仿宋", anchor='center')
        color_preview_label.pack(pady=(0, 5))

        # 颜色预览框
        self.color_preview = tb.Label(color_frame, text="", width=5, background="#36648B")
        self.color_preview.pack(side='left', padx=(0, 5))

        # 颜色选择按钮
        button_color = tk.Button(color_frame, text="选择颜色", height=1, width=10,
                                 font="仿宋", command=self.choose_color)
        button_color.pack(side='left')

        # 字体选择相关控件
        font_frame = tb.Frame(btn_frame)
        font_frame.pack(side='left', padx=(10, 5), pady=10)

        # 字体选择标签
        font_label = tb.Label(font_frame, text="标题字体设置", width=15, anchor='center')
        font_label.pack(pady=(0, 5))

        # 字体选择器
        combobox_font = tb.Combobox(font_frame, textvariable=self.font_var, width=10,
                                    font='10', state='readonly', justify='center')
        combobox_font['values'] = ('宋体', '仿宋', '微软雅黑', '楷体', '黑体', '隶书', '幼圆')
        combobox_font.pack(pady=(0, 5))
        combobox_font.bind("<<ComboboxSelected>>", self.choose_font)

        # 字号选择
        size_label = tb.Label(font_frame, text="字号", width=15, anchor='center')
        size_label.pack()
        size_spinbox = tb.Spinbox(font_frame, from_=8, to=72, textvariable=self.font_size_var,
                                  width=5, command=self.update_font_size)
        size_spinbox.pack()

        # ========== 新增：标题字体颜色选择器 ==========
        # 标签（点击后变色）
        self.title_font_color_label = tb.Label(
            font_frame,
            text="标题字体颜色",
            width=15,
            anchor='center',
            foreground="#000000",
            borderwidth=2,
            relief='groove'  # 或 'ridge'、'sunken' 等
        )
        self.title_font_color_label.pack(pady=(10, 0))

        # 颜色选择按钮
        choose_color_btn = tb.Button(
            font_frame, text="选择颜色", bootstyle="secondary",
            command=self.choose_title_font_color
        )
        choose_color_btn.pack(pady=(5, 10))

        # 行列尺寸设置
        size_frame = tb.Frame(btn_frame)
        size_frame.pack(side='left', padx=(10, 5))

        # 标题行高设置
        title_height_label = tb.Label(size_frame, text="标题行高", width=15, anchor='center')
        title_height_label.pack()
        title_height_spinbox = tb.Spinbox(size_frame, from_=10, to=100,
                                          textvariable=self.title_height_var, width=5)
        title_height_spinbox.pack(pady=(0, 10))

        # 内容行高设置
        row_height_label = tb.Label(size_frame, text="内容行高", width=15, anchor='center')
        row_height_label.pack()
        row_height_spinbox = tb.Spinbox(size_frame, from_=10, to=100,
                                        textvariable=self.row_height_var, width=5)
        row_height_spinbox.pack()

        # 加粗选项
        check_bold = tb.Checkbutton(size_frame, text="加粗", width=4, variable=self.bold_var,
                                    command=self.toggle_bold)
        check_bold.pack(pady=(10, 0))

        # 列宽设置
        col_width_frame = tb.Frame(btn_frame)
        col_width_frame.pack(side='left', padx=(10, 5), pady=10)

        col_width_label = tb.Label(col_width_frame, text="列宽及其状态设置 (A-I)", width=20, anchor='center')
        col_width_label.pack()

        # 列宽输入框与提示信息（A - I）
        self.col_width_entries = {}

        # 每列对应的中文提示
        col_tips = {
            'A': '日期',
            'B': '昵称',
            'C': '姓名',
            'D': '电话',
            'E': '地址',
            'F': '主播',
            'G': '作品',
            'H': '金额',
            'I': '备注'
        }

        for col in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']:
            frame = tb.Frame(col_width_frame)
            frame.pack(side='left', padx=2)

            # 显示小开关
            if col in ['A', 'C', 'D', 'E']:  # 这四列用“铆”替代小开关
                switch_label = tb.Label(frame, text=" 📌", width=3)
                switch_label.pack()
            else:
                switch = tb.Checkbutton(frame, variable=self.col_switch_vars[col], bootstyle="round-toggle",
                                        command=lambda c=col: self.toggle_col_entry_state(c))
                switch.pack()

            # 所有列都显示输入框
            entry = tb.Entry(frame, textvariable=self.col_width_vars[col], width=3)
            entry.pack()

            # 初始化输入框状态
            if not self.col_switch_vars[col].get():
                entry.config(state='readonly')

            self.col_width_entries[col] = entry

            # 提示文字标签（纵向显示）
            tip_label = tb.Label(frame, text=col_tips[col], width=6, font=('仿宋', 10), foreground='black',
                                 anchor='center')
            tip_label.pack()

        # 开始处理按钮
        button_deal = tb.Button(btn_frame, text="开始处理", command=self.process_file)
        button_deal.pack(side='right', padx=(10, 5), pady=10)

        btn_frame.pack(pady=10)

        # -日志区
        log_label = tb.Label(root, text="处理日志：", anchor='w')
        log_label.pack(fill='x', padx=10)

        log_frame_outer = tb.Frame(root, style="Log.TFrame", height=300)
        log_frame_outer.pack(fill='x', padx=10, pady=(0, 5))
        log_frame_outer.pack_propagate(False)

        self.log_canvas = tk.Canvas(log_frame_outer, bg="#f0f4ff", highlightthickness=0, height=280)
        self.log_scrollbar = tb.Scrollbar(log_frame_outer, orient="vertical", command=self.log_canvas.yview)
        self.log_inner = tb.Frame(self.log_canvas, style="LogInner.TFrame")

        self.log_inner.bind(
            "<Configure>",
            lambda e: self.log_canvas.configure(scrollregion=self.log_canvas.bbox("all"))
        )
        self.log_canvas.create_window((0, 0), window=self.log_inner, anchor="nw")
        self.log_canvas.configure(yscrollcommand=self.log_scrollbar.set)

        self.log_canvas.pack(side="left", fill="both", expand=True, padx=10, pady=10)
        self.log_scrollbar.pack(side="right", fill="y")

        self.log_lines = []

        # 底部标签信息
        info_bar = AppInfoBar(self.root)
        info_bar.pack(side='bottom', fill='x')

    # 配置栏输入框placeholder效果方法
    def on_entry_focus_in(self, event):
        if self.new_profile_entry.get() == "新配置名":
            self.new_profile_entry.delete(0, tk.END)
    def on_entry_focus_out(self, event):
        if not self.new_profile_entry.get():
            self.new_profile_entry.insert(0, "新配置名")

    def update_profile_list(self):
        """更新配置文件下拉列表"""
        profiles = list(self.config_manager.configs.keys())
        self.profile_combobox['values'] = profiles
        self.profile_combobox.set('default')

    def save_new_profile(self):
        """保存当前配置为新配置文件"""
        name = self.new_profile_entry.get().strip()
        if not name or name in ['default', '新配置名']:
            messagebox.showwarning("错误", "请输入合法的配置名称！")
            return

        config = {
            'title_color': self.color_var.get(),
            'title_font_color': self.title_font_color_var.get(),
            'font_name': self.font_var.get(),
            'font_size': self.font_size_var.get(),
            'bold': self.bold_var.get(),
            'title_height': self.title_height_var.get(),
            'row_height': self.row_height_var.get(),
            'col_widths': {col: var.get() for col, var in self.col_width_vars.items()},
            'col_switches': {col: var.get() for col, var in self.col_switch_vars.items()},
        }

        self.config_manager.save_config(name, config)
        self.update_profile_list()
        messagebox.showinfo("成功", f"配置已保存为：{name}")

    def apply_config(self, config):
        """应用配置到界面"""
        # 回显标题背景颜色
        color = config.get('title_color', '#36648B')
        self.color_var.set(color)
        self.color_preview.configure(background=color)  # ✅ 同步更新颜色预览框

        # 回显标题字体颜色
        title_font_color = config.get('title_font_color', '#000000')
        self.title_font_color_var.set(title_font_color)
        if hasattr(self, 'title_font_color_label'):
            self.title_font_color_label.config(foreground=title_font_color)

        # 回显表格参数
        self.font_var.set(config.get('font_name', '仿宋'))
        self.font_size_var.set(config.get('font_size', 12))
        self.bold_var.set(config.get('bold', False))
        self.title_height_var.set(config.get('title_height', 25))
        self.row_height_var.set(config.get('row_height', 20))

        # 恢复列宽参数
        col_widths = config.get('col_widths', {})
        for col, var in self.col_width_vars.items():
            var.set(col_widths.get(col, var.get()))

        # 恢复开关状态
        switches = config.get('col_switches', {})
        for col, var in self.col_switch_vars.items():
            var.set(switches.get(col, True))  # 默认为 True

        # 恢复输入框状态
        for col in self.col_width_vars:
            if not self.col_switch_vars[col].get():
                self.col_width_entries[col].config(state='readonly')

    def on_profile_selected(self, event=None):
        """当选择配置文件时，应用对应的配置"""
        name = self.profile_var.get()
        config = self.config_manager.get_config(name)
        self.apply_config(config)

    def toggle_col_entry_state(self, col):
        """根据开关状态更新输入框的可编辑状态"""
        state = 'normal' if self.col_switch_vars[col].get() else 'readonly'
        self.col_width_entries[col].config(state=state)

    def refresh_history(self):
        """刷新历史记录显示"""
        for widget in self.history_frame.winfo_children():
            widget.destroy()

        for idx, path in enumerate(self.file_history):
            row = tb.Frame(self.history_frame)
            row.pack(fill='x', pady=1)

            label = tb.Label(row, text=path, anchor='w')
            label.pack(side='left', fill='x', expand=True)
            label.bind("<Button-1>", lambda e, p=path: self.file_var.set(p))

            del_btn = tb.Button(
                row,
                text="X",
                width=2,
                bootstyle="danger-outline",
                command=lambda i=idx: self.delete_history(i)
            )
            del_btn.pack(side='right', padx=2)

    def delete_history(self, idx):
        """删除指定索引的历史记录"""
        if 0 <= idx < len(self.file_history):
            del self.file_history[idx]
            self.refresh_history()

    def select_file(self):
        """选择Excel文件"""
        file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")])
        if file_path:
            self.file_var.set(file_path)
            if file_path not in self.file_history:
                self.file_history.insert(0, file_path)
                self.refresh_history()

    # 颜色选择器（带位置控制）
    def choose_color(self):
        # 创建一个临时顶层窗口用于定位
        color_window = tk.Toplevel(self.root)
        color_window.title("背景颜色选择器")
        color_window.resizable(False, False)

        # 获取按钮的位置和尺寸
        x = self.color_preview.winfo_rootx() + self.color_preview.winfo_width() + 10
        y = self.color_preview.winfo_rooty()

        # 初始化为默认颜色
        selected_color = [None, None]

        def on_color_selected():
            nonlocal selected_color
            selected_color = tk.colorchooser.askcolor(title="请进行选择！", parent=color_window)
            if selected_color[1]:
                self.color_var.set(selected_color[1])
                self.color_preview.configure(background=selected_color[1])
                self.add_log(f"已选择十六进制颜色值: {selected_color[1]}", error=False)
            color_window.destroy()

        # 模拟点击后立即调用颜色选择器
        self.root.after(100, on_color_selected)

        # 设置窗口位置（按钮右侧）
        color_window.geometry(f"+{x}+{y}")
        color_window.transient(self.root)  # 设置为临时窗口
        color_window.grab_set()  # 捕获事件
        self.root.wait_window(color_window)  # 等待窗口关闭

    # 字体选择器
    def choose_font(self, event=None):
        selected_font = self.font_var.get()
        self.add_log(f"已选择字体: {selected_font}", error=False)

    def choose_title_font_color(self):
        """选择标题字体颜色"""
        color = colorchooser.askcolor(
            title="选择标题字体颜色",
            initialcolor=self.title_font_color_var.get(),
            parent=self.root
        )
        if color[1]:
            self.title_font_color_var.set(color[1])
            self.title_font_color_label.config(foreground=color[1])  # 修改 Label 字体颜色
            self.add_log(f"已选择标题字体颜色：{color[1]}", error=False)

    # 更新字体大小
    def update_font_size(self):
        self.add_log(f"字体大小设置为: {self.font_size_var.get()}", error=False)

    # 切换加粗
    def toggle_bold(self):
        status = "已启用" if self.bold_var.get() else "已禁用"
        self.add_log(f"{status}加粗功能", error=False)

    def process_file(self):
        """处理Excel文件"""
        file_path = self.file_var.get()
        if not file_path:
            self.add_log("请先选择Excel文件", error=True)
            return

        # 收集所有配置参数
        config = {
            'title_color': self.color_var.get(),
            'title_font_color': self.title_font_color_var.get(),
            'font_name': self.font_var.get(),
            'font_size': self.font_size_var.get(),
            'bold': self.bold_var.get(),
            'title_height': self.title_height_var.get(),
            'row_height': self.row_height_var.get(),
            'col_widths': {
                col: var.get()
                for col, var in self.col_width_vars.items()
                if self.col_switch_vars[col].get()  # ⬅️ 只传开启的列宽参数
            },
            'col_switches': {
                col: var.get()
                for col, var in self.col_switch_vars.items()
            },
        }

        process_excel(file_path, self.add_log, config)

    def add_log(self, msg, file_path=None, error=False):
        """添加日志信息"""
        row = tb.Frame(self.log_inner)
        color = "#d9534f" if error else "#333"
        label = tb.Label(row, text=msg, anchor='w', foreground=color, wraplength=600)
        label.pack(side='left', fill='x', expand=True)

        if file_path and os.path.exists(file_path):
            open_btn = tb.Button(row, text="打开文件夹", bootstyle="info-outline", width=10,
                                 command=lambda p=file_path: os.startfile(os.path.dirname(p)))
            open_btn.pack(side='right', padx=2)

        if self.log_lines:
            row.pack(fill='x', pady=1, anchor='w', before=self.log_lines[0])
            self.log_lines.insert(0, row)
        else:
            row.pack(fill='x', pady=1, anchor='w')
            self.log_lines.append(row)
        self.root.after(100, lambda: self.log_canvas.yview_moveto(0.0))


if __name__ == "__main__":
    app = tb.Window(themename="litera")
    ExcelApp(app)
    app.iconbitmap(os.path.join('assets/', 'cshExcel32.ico'))  # 设置图标

    # 设置窗口大小并居中
    center_window(app, 1000, 850)  # 主窗口大小为 1100x850

    app.mainloop()
